/* Soubor je ulozen v kodovani UTF-8.
 * Kontrola kódování: Příliš žluťoučký kůň úpěl ďábelské ódy. */

package cz.vse.adventura.po1715.xforv00_forejt.hra;

import cz.pecinovsky.english.pojj.adv_framework.game_gui.IBagG;
import cz.pecinovsky.english.pojj.adv_framework.game_gui.IListener;
import cz.pecinovsky.english.pojj.adv_framework.game_gui.IObjectG;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;





/*******************************************************************************
 * Instance třídy {@code Batoh} představují batoh, do kterého uživatel
 * při hře ukládá předměty
 *
 * @author    Vladimír Forejt
 * @version   0.00.000
 */
public class Batoh implements IBagG
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    /** Schránka na přenášené předměty. */
    private static final Batoh batoh = new Batoh();

    // Kapacita batohu
    private static final int kapacita = 5;

//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================

/** Kolekce předmětů v batohu. */
    private final Collection<Předmět> obsah = new ArrayList<Předmět>();

/** Posluchači batohu - PROČ FINAL??*/
    private Collection<IListener<IBagG>> listeners =
                        new ArrayList<IListener<IBagG>>();

//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     *Vrací odkaz na batoh
     */
    static Batoh getBatoh()
    {
        return batoh;
    }


    /***************************************************************************
     *Batoh stačí jeden
     */
    private Batoh()
    {
    }



//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================

    /***************************************************************************
     * Vrátí kapacitu batohu, tj. kolik předmětů se do něj vejde.
     *
     * @return Kapacita batohu
     */
    @Override
    public int getCapacity()
    {
        return kapacita;
    }

    /***************************************************************************
     * Vrátí kolekci předmětů uložených v batohu.
     *
     * @return Kolekce predmetu v batohu
     */
    @Override
    public Collection<? extends IObjectG> getObjects()
    {
        return Collections.unmodifiableCollection(obsah);
    }


//== OSTATNÍ NESOUKROMÉ METODY INSTANCÍ ========================================

    /***************************************************************************
     * Inicializuje jedináčka a připraví jej pro novou hru.
     */
    static void inicializuj()
    {
        batoh.obsah.clear();
    }

    /** Přidá do batohu předmět v parametru
     *
     * @param předmět
     * @return boolean přidáno
     */
    boolean přidej(Předmět předmět)
    {
        boolean přidáno = false;
        if(obsah.size() < kapacita) {
            obsah.add(předmět);
            noticeListeners();
            přidáno = true;
        }
        return přidáno;
    }

    /** Odebere z batohu předmět podle názvu v parametru
     *
     * @param nazev Název předmětu, který se má odebrat
     * @return Předmět požadovaný když je nalezen, jinal {@code null}
     */
    Předmět odeber (String nazev)
    {
        Předmět požadovaný = null;
        for(Předmět objekt : obsah)
        {
            if(objekt.getName().equalsIgnoreCase(nazev)) {
                požadovaný = objekt;
                obsah.remove(objekt);
                noticeListeners();
                break;                  //--------------------------->
            }
        }
        return požadovaný;
    }

    /***************************************************************************
     * Zjistí, zda batoh obsahuje předmět se zadaným názvem.
     *
     * @param  název Název předmětu v batohu
     * @return {@code true} pokud je předmět v batohu, jinak {@code falše}
     */
    boolean obsahuje(String název)
    {
        boolean nasel = false;
        String jméno;
        for (Předmět předmět : obsah) {
            jméno = předmět.getName();
            nasel = jméno.equalsIgnoreCase(název);
            if(nasel) {
                break;                       //------------------------->
            }
        }
        return nasel;
    }

    /***************************************************************************
     * Přidá zadaného posluchače do seznamu posluchačů,
     * které zpravuje o změně množiny předmětů v batohu.
     *
     * @param listener Přihlašovaný posluchač
     */
    //@Override
    public void addListener(IListener<IBagG> listener) {
        listeners.add(listener);
    }

    /***************************************************************************
     * Odebere zadaného posluchače ze seznamu posluchačů,
     * které zpravuje o změně množiny předmětů v batohu.
     *
     * @param listener Odhlašovaný posluchač
     */
    //@Override
    public void removeListener(IListener<IBagG> listener) {
        listeners.remove(listener);
    }

   

//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================

    /***************************************************************************
     * Upozorní přihlášené posluchače, že se obsah batohu změnil
     */
    private void noticeListeners() {
        for (IListener<IBagG> listener : listeners) {
            listener.notice(this);
        }
    }
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== INTERNÍ DATOVÉ TYPY =======================================================
//== TESTY A METODA MAIN =======================================================
//
//     /***************************************************************************
//      * Testovací metoda.
//      */
//     public static void test()
//     {
//         Batoh instance = new Batoh();
//     }
//     /** @param args Parametry příkazového řádku - nepoužívané. */
//     public static void main(String[] args)  {  test();  }
}
